package com.acmedcare.framework.exchange.center.endpoint;

import com.acmedcare.framework.exchange.center.common.Page;
import com.acmedcare.framework.exchange.center.core.Const;
import com.acmedcare.framework.exchange.center.endpoint.exception.InvalidRequestParameterException;
import com.acmedcare.framework.exchange.center.endpoint.service.StageService;
import com.acmedcare.framework.exchange.center.entity.bean.Stage;
import com.acmedcare.framework.exchange.center.entity.bean.StageConfig;
import com.acmedcare.framework.exchange.center.entity.dto.StageDetailDto;
import com.acmedcare.framework.exchange.center.entity.dto.StageQueryDto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Api(tags = "环境配置")
@RequestMapping("/stages")
public class StageEndpoint {

  final StageService stageService;

  final RabbitTemplate rabbitTemplate;

  final ObjectMapper objectMapper;

  public StageEndpoint(
      StageService stageService, RabbitTemplate rabbitTemplate,
      ObjectMapper objectMapper) {
    this.stageService = stageService;
    this.rabbitTemplate = rabbitTemplate;
    this.objectMapper = objectMapper;
  }

  @GetMapping("/list")
  @ApiOperation("获取环境配置列表")
  public ResponseEntity<Page<Stage>> getList(StageQueryDto queryDto) {

    return ResponseEntity.ok(stageService.getList(queryDto));
  }

  @GetMapping("/{id}")
  @ApiOperation("获取环境配置详情")
  public ResponseEntity<StageDetailDto> getDetail(@PathVariable Long id)
      throws InvalidRequestParameterException {

    return ResponseEntity.ok(stageService.getDetailDto(id));
  }

  @PostMapping
  @ApiOperation("新增环境配置")
  public ResponseEntity add(@RequestBody StageDetailDto stageDetailDto)
      throws InvalidRequestParameterException {

    valid(stageDetailDto);
    stageService.insertDetailDto(stageDetailDto);
    return ResponseEntity.ok().build();
  }

  @PutMapping
  @ApiOperation("更新环境配置")
  public ResponseEntity update(@RequestBody StageDetailDto stageDetailDto)
      throws InvalidRequestParameterException {

    valid(stageDetailDto);
    stageService.updateStage(stageDetailDto);
    return ResponseEntity.ok().build();
  }

  @DeleteMapping("/configs/{id}")
  @ApiOperation("删除环境配置值")
  public ResponseEntity delete(@PathVariable Long id) {
    stageService.deleteStageConfig(id);

    return ResponseEntity.ok().build();
  }

  @PostMapping("/command/{id}")
  @ApiOperation("发布指定环境配置")
  public ResponseEntity publish(@PathVariable Long id)
      throws InvalidRequestParameterException, JsonProcessingException {

    StageDetailDto stageDetailDto = stageService.getDetailDto(id);
    rabbitTemplate.setExchange(Const.StageExchangeName);
    rabbitTemplate.convertAndSend(objectMapper.writeValueAsString(stageDetailDto));
    return ResponseEntity.ok().build();
  }

  private void valid(StageDetailDto stageDetailDto) throws InvalidRequestParameterException {

    if (StringUtils.isEmpty(stageDetailDto.getStage().getStageName())) {

      throw new InvalidRequestParameterException("环境名不允许为空!");
    }

    if (stageDetailDto.getStageConfig().isEmpty()) {
      return;
    }

    for (StageConfig config : stageDetailDto.getStageConfig()) {

      if (StringUtils.isEmpty(config.getConfigName()) || StringUtils
          .isEmpty(config.getConfigValue())
          || StringUtils.isEmpty(config.getStageName())) {

        throw new InvalidRequestParameterException("配置环境值不允许为空!");
      }
    }
  }
}
